#include "TypeConverter.h"
#include <QDebug>
#include <QString>
#include <QVariant>
#include <exception>
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

// 定义py命名空间别名
namespace py = pybind11;

QVariant TypeConverter::pyObjectToQVariant(const pybind11::object &obj) {
  if (obj.is_none()) {
    return QVariant();
  }

  try {
    // 尝试转换为不同的Qt类型
    if (pybind11::isinstance<pybind11::str>(obj)) {
      std::string str = obj.cast<std::string>();
      // 使用fromUtf8处理UTF-8编码的字符串
      return QString::fromLocal8Bit(str.c_str());
    }

    if (pybind11::isinstance<pybind11::int_>(obj)) {
      int val = obj.cast<int>();
      return val;
    }

    if (pybind11::isinstance<pybind11::float_>(obj)) {
      double val = obj.cast<double>();
      return val;
    }

    if (pybind11::isinstance<pybind11::bool_>(obj)) {
      bool val = obj.cast<bool>();
      return val;
    }

    // 默认转换为字符串
    std::string str = pybind11::str(obj).cast<std::string>();
    // 使用fromUtf8处理UTF-8编码的字符串
    return QString::fromUtf8(str.c_str());
  } catch (const std::exception &e) {
    qWarning() << "Python对象转换为QVariant失败:" << e.what();
    std::string str = pybind11::str(obj).cast<std::string>();
    // 使用fromUtf8处理UTF-8编码的字符串
    return QString::fromUtf8(str.c_str());
  }
}

pybind11::object TypeConverter::qVariantToPyObject(const QVariant &variant) {
  if (!variant.isValid()) {
    return pybind11::none();
  }

  switch (variant.type()) {
  case QVariant::String:
    return pybind11::str(variant.toString().toUtf8().constData());

  case QVariant::Int:
    return pybind11::int_(variant.toInt());

  case QVariant::Double:
    return pybind11::float_(variant.toDouble());

  case QVariant::Bool:
    return pybind11::bool_(variant.toBool());

  default:
    // 默认转换为字符串
    return pybind11::str(variant.toString().toUtf8().constData());
  }
}

bool TypeConverter::isConvertible(const QVariant &variant) {
  // 检查是否可以转换为Python对象
  switch (variant.type()) {
  case QVariant::Invalid:
  case QVariant::String:
  case QVariant::Int:
  case QVariant::Double:
  case QVariant::Bool:
    return true;

  default:
    return false;
  }
}